﻿Public Class frmTunnelConfig
    Private WithEvents Config As OpenVPNWinSvc.Library.OpenVPNConfiguration
    Private WithEvents CfgEdit As New frmConfigEdit
    Private _TunnelName As String

    'TODO: ' "disable tunnel" unavailable while tunnel UP or Listening


    Public Property TunnelName As String
        Get
            Return _TunnelName
        End Get
        Set(value As String)
            _TunnelName = value
            Call Reset()
        End Set
    End Property

    Public Sub Reset()
        Me.Text = _TunnelName & " - Configuration Editor"
        chkDisable.Checked = False
        lsvConfig.Items.Clear()
        Config = New OpenVPNWinSvc.Library.OpenVPNConfiguration
        Config.ReadConfiguration()
    End Sub

    Private Sub btnCfgAdd_Click(sender As System.Object, e As System.EventArgs) Handles btnCfgAdd.Click
        Dim N As New frmConfigEdit
        N.ShowDialog(Me)
        If N.Result = MsgBoxResult.Ok Then
            lsvConfig.Items.Add(N.Setting).SubItems.Add(N.Value)
            lsvConfig.EnsureVisible(lsvConfig.Items.Count - 1)
        End If
        N = Nothing
    End Sub

    Private Sub lsvConfig_SelectedIndexChanged(sender As System.Object, e As System.EventArgs) Handles lsvConfig.SelectedIndexChanged
        Select Case lsvConfig.SelectedItems.Count
            Case 0
                btnCfgAdd.Enabled = True
                btnCfgRemove.Enabled = False
                btnCfgEdit.Enabled = False
            Case 1
                btnCfgAdd.Enabled = True
                btnCfgRemove.Enabled = True
                btnCfgEdit.Enabled = True
            Case Is > 1
                btnCfgAdd.Enabled = True
                btnCfgRemove.Enabled = True
                btnCfgEdit.Enabled = False
        End Select
    End Sub

    Private Sub Config_SetConfigLine(TunnelName As String, ConfigLine As String) Handles Config.SetConfigLine
        If TunnelName = _TunnelName Then
            Dim NewItem As New ListViewItem
            NewItem.Text = GetSetting(ConfigLine)
            If Not GetValue(ConfigLine) = "" Then
                NewItem.SubItems.Add(GetValue(ConfigLine))
            End If
            lsvConfig.Items.Add(NewItem)
        End If
    End Sub

    Private Sub Config_SetDisable(TunnelName As String) Handles Config.SetDisable
        If TunnelName = _TunnelName Then
            chkDisable.Checked = True
        End If
    End Sub

    Private Function GetSetting(CfgLine As String) As String
        Dim SpcPos As Integer = InStr(CfgLine, " ")
        If SpcPos = 0 Then
            Return CfgLine
        Else
            Return Microsoft.VisualBasic.Left(CfgLine, SpcPos - 1)
        End If
    End Function

    Private Function GetValue(CfgLine As String) As String
        Dim SpcPos As Integer = InStr(CfgLine, " ")
        If SpcPos = 0 Then
            Return ""
        Else
            Return Microsoft.VisualBasic.Mid(CfgLine, SpcPos + 1)
        End If
    End Function

    Private Sub btnReset_Click(sender As System.Object, e As System.EventArgs) Handles btnReset.Click
        Call Reset()
    End Sub

    Private Sub btnCfgRemove_Click(sender As System.Object, e As System.EventArgs) Handles btnCfgRemove.Click
        While lsvConfig.SelectedItems.Count > 0
            lsvConfig.SelectedItems(0).Remove()
        End While
    End Sub

    Private Sub btnCancel_Click(sender As System.Object, e As System.EventArgs) Handles btnCancel.Click
        lsvConfig.Clear()
        Me.Close()
    End Sub


    Private Sub btnApply_Click(sender As System.Object, e As System.EventArgs) Handles btnApply.Click
        Try
            Dim Value As String
            Config.ClearTunnelCfg(_TunnelName)
            If chkDisable.Checked Then Config.WriteTunnelCfg(_TunnelName, "disabled")
            For Each cfgset As ListViewItem In lsvConfig.Items
                If cfgset.SubItems.Count = 2 Then
                    Value = cfgset.SubItems(1).Text
                    Config.WriteTunnelCfg(_TunnelName, cfgset.Text, Value)
                Else
                    Config.WriteTunnelCfg(_TunnelName, cfgset.Text)
                End If
            Next
        Catch ex As Exception
            MsgBox("Unable to write tunnel config: " & ex.Message)
        End Try
        Me.Close()
    End Sub

    Private Sub btnCfgEdit_Click(sender As System.Object, e As System.EventArgs) Handles btnCfgEdit.Click
        If lsvConfig.SelectedItems.Count = 1 Then
            Dim N As New frmConfigEdit
            Dim I As ListViewItem = lsvConfig.SelectedItems(0)
            If I.SubItems.Count = 2 Then
                N.txtValue.Text = lsvConfig.SelectedItems(0).SubItems(1).Text
            Else
                N.txtValue.Text = ""
            End If
            N.cmbSetting.Text = I.Text
            N.cmbSetting.Enabled = False
            N.ShowDialog(Me)
            If I.SubItems.Count = 2 Then
                I.SubItems(1).Text = N.Value
            Else
                I.SubItems.Add(N.Value)
            End If
            N = Nothing
        End If
    End Sub

    Private Sub btnImport_Click(sender As System.Object, e As System.EventArgs) Handles btnImport.Click
        Dim ResMsg As MsgBoxResult
        If lsvConfig.Items.Count > 0 Then
            ' existing config. replace=
            ResMsg = MsgBox("Current tunnel configuration will be replaced." & vbCrLf & "Continue?", vbYesNo Or vbQuestion, "Import OpenVPN Configuration")
            If ResMsg = MsgBoxResult.Yes Then
                ' ok, replace existing config
                Call BrowseConfigFile()
            End If
        Else
            ' no existing config
            Call BrowseConfigFile()
        End If
    End Sub

    Private Sub BrowseConfigFile()
        Dim Dlg As New OpenFileDialog
        Dim ResDlg As DialogResult
        Dlg.AddExtension = True
        Dlg.AutoUpgradeEnabled = True
        Dlg.CheckFileExists = True
        Dlg.CheckPathExists = True
        Dlg.DefaultExt = "ovpn"
        Dlg.Filter = "OpenVPN Configuration Files (*.ovpn)|*.ovpn|UNIX Configuration Files (*.conf)|*.conf|Text Files (*.txt)|*.txt|All Files (*.*)|*.*"
        Dlg.FilterIndex = 0
        Dlg.Multiselect = False
        Dlg.RestoreDirectory = True
        Dlg.Title = "Import OpenVPN Configuration"
        ResDlg = Dlg.ShowDialog()
        If ResDlg = Windows.Forms.DialogResult.OK Then
            Call LoadConfigFile(Dlg.FileName)
        End If
        Dlg = Nothing
    End Sub

    Private Sub LoadConfigFile(FileName As String)
        Dim ReadLine As String = ""
        Dim NewItem As ListViewItem
        Dim NewValue As String = ""
        Dim CommentStart As Integer
        lsvConfig.Items.Clear()
        Try
            Using sr As New System.IO.StreamReader(FileName)
                While Not sr.EndOfStream
                    ReadLine = sr.ReadLine
                    ' ignore empty lines or comments
                    If (Not ReadLine.StartsWith("#")) And (Not ReadLine = "") Then
                        ' read max 8k per line
                        ReadLine = Microsoft.VisualBasic.Left(ReadLine, 8192)
                        ' ignore inline comments
                        CommentStart = InStr(ReadLine, "#")
                        If Not CommentStart = 0 Then ReadLine = Microsoft.VisualBasic.Left(ReadLine, CommentStart - 1)
                        NewItem = New ListViewItem
                        NewItem.Text = GetSetting(ReadLine)
                        NewValue = GetValue(ReadLine)
                        If Not NewValue = "" Then NewItem.SubItems.Add(NewValue)
                        lsvConfig.Items.Add(NewItem)
                    End If
                End While
                If Not NewItem Is Nothing Then NewItem.EnsureVisible()
                lsvConfig.Refresh()
            End Using
        Catch ex As Exception
            MsgBox("Could not import configuration: " & ex.Message, vbCritical Or vbOKOnly, "Import OpenVPN Configuration")
        End Try
    End Sub

End Class